package com.goa.task;

import com.goa.entity.DeviceCron;
import com.goa.mapper.DeviceTaskMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.lang.reflect.Field;
import java.util.*;

@Slf4j
//@Component
public class JobScheduler2a {  

    @Autowired
    private final DeviceTaskMapper deviceTaskMapper;

    // 创建 Spring 应用上下文
    ApplicationContext context = new AnnotationConfigApplicationContext("com.goa"); // 包名

    // 获取 SchedulerUtil 实例
    SchedulerUtil schedulerUtil = context.getBean(SchedulerUtil.class);

    // 获取 Scheduler 实例
    Scheduler scheduler = schedulerUtil.getScheduler();

    public JobScheduler2a(DeviceTaskMapper deviceTaskMapper) {
        this.deviceTaskMapper = deviceTaskMapper;  
    }

    // 在项目启动时调用一次同步任务
    @SneakyThrows
//    @PostConstruct
    public void init() {
        syncJobs();
    }

//    @Scheduled(cron = "0 * * * * ?") //之后每分钟一次刷新 或者按天进行更新定时任务
    public void syncJobs() throws SchedulerException {
        log.info("=============================执行刷新定时任务=============================");
        try {
            List<DeviceCron> deviceCrons = deviceTaskMapper.findAll();
            Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals("group1"));
            Set<JobKey> jobsToDelete = new HashSet<>(jobKeys);
            // 删除不再需要的任务
            for (JobKey jobKey : jobsToDelete) {
                scheduler.deleteJob(jobKey);
            }

            // 重新添加新任务
            for (DeviceCron deviceCron : deviceCrons) {
                addJob(deviceCron);
            }
        } catch (Exception e) {
            log.error("同步任务失败", e);
        }
    }

    public  void addJob(DeviceCron deviceCron) throws SchedulerException {
        try {
            // 确保 DynamicJob 类能够加载
            Class.forName("com.goa.task.DynamicJob");

            JobDataMap jobDataMap = new JobDataMap(convertToMap(deviceCron));
            JobDetail jobDetail = JobBuilder.newJob(DynamicJob.class)
                    .withIdentity(deviceCron.getJobName(), "group1")
                    .withDescription(deviceCron.getDescription())
                    .usingJobData("addressIp", deviceCron.getAddressIp())
                    .usingJobData("id", deviceCron.getId())
                    .usingJobData(jobDataMap)
                    .build();

            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(deviceCron.getJobName(), "group1")
                    .withSchedule(CronScheduleBuilder.cronSchedule(deviceCron.getCronExpression()))
                    .build();

            // 安排定时任务
            scheduler.scheduleJob(jobDetail, trigger);
            log.info("成功添加任务: {}", deviceCron.getJobName());
        } catch (ClassNotFoundException e) {
            log.error("无法加载 DynamicJob 类", e);
            throw new SchedulerException("无法加载 DynamicJob 类", e);
        } catch (SchedulerException e) {
            log.error("调度任务失败", e);
            throw e; // 重新抛出异常
        }
    }


    public static Map<String, Object> convertToMap(Object entity) {
        Map<String, Object> map = new HashMap<>();
        // 获取实体类的所有字段
        Field[] fields = entity.getClass().getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true); // 允许访问私有字段
            try {
                map.put(field.getName(), field.get(entity)); // 将字段名和字段值放入 Map
            } catch (IllegalAccessException e) {
                e.printStackTrace(); // 处理异常
            }
        }
        return map;
    }
}